package com.cn.common.core.codc;

import java.util.List;

import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPipeline;
import io.netty.handler.codec.ByteToMessageDecoder;
import com.cn.common.core.model.Request;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.stream.ChunkedWriteHandler;

/**
 * 数据包解码器
 * <pre>
 * 数据包格式
 * +——----——+——-----——+——----——+——----——+——-----——+
 * |  包头	|  模块号      |  命令号    |   长度     |   数据       |
 * +——----——+——-----——+——----——+——----——+——-----——+
 * </pre>
 * 包头4字节
 * 模块号2字节
 * 命令号2字节
 * 长度4字节(数据部分占有字节数量)
 *
 * @author -jiawuwei-
 */
public class RequestDecoder extends ByteToMessageDecoder {

    /**
     * 数据包基本长度
     */
    public static int BASE_LENTH = 4 + 2 + 2 + 4;

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf buffer, List<Object> out) throws Exception {
/*        Channel channel = ctx.channel();
        ChannelPipeline pipeline = channel.pipeline();
        List<String> names = pipeline.names();
        System.out.println("当前线程====" + Thread.currentThread().getName());
        byte[] src = new byte[buffer.readableBytes()];
        ByteBuf copy = buffer.copy(0, buffer.readableBytes());
        boolean flag = false;
        while (copy.readableBytes() > 4) {
            copy.markReaderIndex();
            if (copy.readInt() == ConstantValue.HEADER_FLAG) {
                flag = true;
                break;
            }
            //恢复到标记位
            copy.resetReaderIndex();
            //略过一个字节
            copy.readByte();
        }
        if (flag) {*/
   /*         pipeline.remove(HttpServerCodec.class);
            pipeline.remove(ChunkedWriteHandler.class);
            pipeline.remove(HttpObjectAggregator.class);
            pipeline.remove(WebSocketServerProtocolHandler.class);*/
            System.out.println("当前线程========" + Thread.currentThread().getName());
            while (true) {
                if (buffer.readableBytes() >= BASE_LENTH) {
                    //第一个可读数据包的起始位置
                    int beginIndex;

                    while (true) {
                        //包头开始游标点
                        beginIndex = buffer.readerIndex();
                        //标记初始读游标位置
                        buffer.markReaderIndex();
                        if (buffer.readInt() == ConstantValue.HEADER_FLAG) {
                            break;
                        }
                        //未读到包头标识略过一个字节
                        buffer.resetReaderIndex();
                        buffer.readByte();

                        //不满足
                        if (buffer.readableBytes() < BASE_LENTH) {
                            return;
                        }
                    }
                    //读取命令号
                    short module = buffer.readShort();
                    short cmd = buffer.readShort();

                    //读取数据长度
                    int lenth = buffer.readInt();
                    if (lenth < 0) {
                        ctx.channel().close();
                    }

                    //数据包还没到齐
                    if (buffer.readableBytes() < lenth) {
                        buffer.readerIndex(beginIndex);
                        return;
                    }

                    //读数据部分
                    byte[] data = new byte[lenth];
                    buffer.readBytes(data);

                    Request message = new Request();
                    message.setModule(module);
                    message.setCmd(cmd);
                    message.setData(data);
                    //解析出消息对象，继续往下面的handler传递
                    out.add(message);
                    //ctx.fireChannelRead(buffer);
                } else {
                    break;
                }
            }
       /* } else {
            //注入remove的顺序，先remove掉当前解码器相关的handler，然后remove掉自身，然后向下传递。
            pipeline.remove(ResponseEncoder.class);
            pipeline.remove(RequestDecoder.class);
            ctx.fireChannelRead(buffer);
        }*/


        ///return ;
    }

    //当channel的活动状态变为非活动状态，该方法会被调用一次
    @Override
    protected void decodeLast(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
        //该方法默认调用decode方法。
        super.decodeLast(ctx, in, out);
    }
}
